package com.liveneo.adapter.base.support;

import java.util.HashMap;
import java.util.Map;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;

/**
 * 日志记录 工具类
 * 
 * @author fucy
 *
 */
public class LogUtils {
    // 日志id标示
    private static final String        MOBILE_LOG_ID     = "mobileLog";
    private static final String        CXF_LOG_ID        = "cxfLog";
    private static final String        OTHER_LOG_ID      = "otherLog";
    private static final String        OUTINTERFACE_LOG_ID = "outinterfaceLog";
    // 日志记录时的前缀
    private static final String        MOBILE_LOG_PREFIX = "移动端请求";
    private static final String        CXF_LOG_PREFIX    = "CXF接口请求";
    private static final String        OTHER_LOG_PREFIX  = "其他模块处理";
    private static final String        OUTINTERFACE_LOG_PREFIX  = "对外接口模块处理";
    // 不同模块的日志记录实例对象
    private static final Logger        MOBILE_LOGGER     = Logger.getLogger(MOBILE_LOG_ID);
    private static final Logger        CXF_LOGGER        = Logger.getLogger(CXF_LOG_ID);
    private static final Logger        OTHER_LOGGER      = Logger.getLogger(OTHER_LOG_ID);
    private static final Logger        OUTINTERFACE_LOGGER= Logger.getLogger(OUTINTERFACE_LOG_ID);
    // 模块标识和日志对象的Map
    private static Map<String, Logger> LOGGER_MAP        = new HashMap<String, Logger>();
    // 模块标识和日志记录前缀的Map
    private static Map<String, String> LOGGER_PREFIX_MAP = new HashMap<String, String>();
    static {
        LOGGER_MAP.put(AdapterConstants.MODULE_TYPE_MOBILE, MOBILE_LOGGER);
        LOGGER_MAP.put(AdapterConstants.MODULE_TYPE_CXF, CXF_LOGGER);
        LOGGER_MAP.put(AdapterConstants.MODULE_TYPE_OTHER, OTHER_LOGGER);
        LOGGER_MAP.put(AdapterConstants.OUT_TYPE_INTERFACE, OUTINTERFACE_LOGGER);
        LOGGER_PREFIX_MAP.put(AdapterConstants.MODULE_TYPE_MOBILE, MOBILE_LOG_PREFIX);
        LOGGER_PREFIX_MAP.put(AdapterConstants.MODULE_TYPE_CXF, CXF_LOG_PREFIX);
        LOGGER_PREFIX_MAP.put(AdapterConstants.MODULE_TYPE_OTHER, OTHER_LOG_PREFIX);
        LOGGER_PREFIX_MAP.put(AdapterConstants.OUT_TYPE_INTERFACE, OUTINTERFACE_LOG_PREFIX);
    }

    /**
     * 记录debug日志
     * 
     * @param message 日志信息
     */
    public static final void debug(String message) {
        getCurLogger().log(Level.DEBUG, getLogInfoStartWith() + message);
    }

    /**
     * 记录info日志
     * 
     * @param message 日志信息
     */
    public static final void info(String message) {
        getCurLogger().log(Level.INFO, getLogInfoStartWith() + message);
    }

    /**
     * 记录warn日志
     * 
     * @param message 日志信息
     */
    public static final void warn(String message) {
        getCurLogger().log(Level.WARN, getLogInfoStartWith() + message);
    }

    /**
     * 记录error日志
     * 
     * @param message 日志信息
     */
    public static final void error(String message) {
        getCurLogger().log(Level.ERROR, getLogInfoStartWith() + message);
    }

    /**
     * 记录error日志
     * 
     * @param message 日志信息
     * @param e 错误异常
     */
    public static final void error(String message, Throwable e) {
        getCurLogger().error(getLogInfoStartWith() + message, e);
    }

    /**
     * 获取日志的开头信息
     * 比如：MobileReturnCodeSupportTest.test(53) - 移动端请求批次【aaaaaaaaaa】，....
     * 
     * @return
     */
    private static String getLogInfoStartWith() {
        StringBuffer logInfo = new StringBuffer();
        StackTraceElement[] eles = Thread.currentThread().getStackTrace();
        String curRequestType = ThreadStore.getCurRequestType();
        // ele[0]对应的为Thread，
        for (int i = 1; i < eles.length; i++) {
            StackTraceElement ele = eles[i];
            // 获取调用日志记录的类名，方法和执行代码的行数
            if (ele != null && !LogUtils.class.getName().equals(ele.getClassName())) {
                logInfo.append(StringUtils.substringAfterLast(ele.getClassName(), "."));
                logInfo.append(".");
                logInfo.append(ele.getMethodName());
                logInfo.append("(");
                logInfo.append(ele.getLineNumber());
                logInfo.append("行)");
                break;
            }
        }
        logInfo.append(" - ");
        if (StringUtils.isNotBlank(curRequestType) && LOGGER_PREFIX_MAP.containsKey(curRequestType)) {
            logInfo.append(LOGGER_PREFIX_MAP.get(curRequestType));
        } else {
            logInfo.append(OTHER_LOG_PREFIX);
        }
        logInfo.append("批次【");
        logInfo.append(ThreadStore.getCurRequestUUID());
        logInfo.append("】，");
        return logInfo.toString();
    }

    /**
     * 获取当前日志实例对象
     * 
     * @return
     */
    private static Logger getCurLogger() {
        String curRequestType = ThreadStore.getCurRequestType();
        Logger logger = OTHER_LOGGER;
        if (StringUtils.isNotBlank(curRequestType) && LOGGER_MAP.containsKey(curRequestType)) {
            // 以模块形式记录
            logger = LOGGER_MAP.get(curRequestType);
        }
        return logger;
    }
}
